#region Imports

using System;
using System.Collections.Generic;
using d3PrtDgn.Core.BaseData;

#endregion

namespace d3PrtDgn.Data.Domain.Entity
{
	[Serializable]
    public class User : BaseEntity 
	{
		#region Private Members

		// Primary Key(s) 
		private int id; 
		
		// Properties 
		private string name;
		private string surname;
		private string email;
		private string username; 
		private string password; 
		
		// One-to-many relations 
		private IList<Album> albums;
		private IList<Comment> comments;
		private IList<Vote> votes;		

		#endregion
		
		#region Default ( Empty ) Class Constructor
		
		/// <summary>
		/// default constructor
		/// </summary>
		public User()
		{
			id = 0; 
			name = null;
			surname = null;
			email = null;
			username = null; 
			password = null; 
			albums = null; 
			comments = null; 
			votes = null; 
		}
		
		#endregion // End of Default ( Empty ) Class Constructor
		
		#region Full Constructor
		
		/// <summary>
		/// full constructor
		/// </summary>
		public User(int id, string name, string surname, string username, string password)
		{
			this.id = id;
			this.name = name;
			this.surname = surname;
			this.username = username;
			this.password = password;
			this.albums = null;
			this.comments = null;
			this.votes = null; 
		}
		
		#endregion // End Full Constructor

		#region Public Properties
			
		/// <summary>
		/// Unique identifier
		/// </summary>		
		public virtual int Id
		{
			get { return id; }
			set { isChanged |= (id != value); id = value; }
		} 
	  
		/// <summary>
		/// User's name
		/// </summary>		
		public virtual string Name
		{
			get { return name; }
			set	
			{
				if ( value != null )
					if( value.Length > 50)
						throw new ArgumentOutOfRangeException("Invalid value for Name", value, value.ToString());
				
				isChanged |= (name != value); name = value;
			}
		}

		/// <summary>
		/// User's surname
		/// </summary>		
		public virtual string Surname
		{
			get { return surname; }
			set
			{
				if (value != null)
					if (value.Length > 50)
						throw new ArgumentOutOfRangeException("Invalid value for Surname", value, value.ToString());

				isChanged |= (surname != value); surname = value;
			}
		}

		/// <summary>
		/// User's email
		/// </summary>		
		public virtual string Email
		{
			get { return email; }
			set
			{
				if (value != null)
					if (value.Length > 50)
						throw new ArgumentOutOfRangeException("Invalid value for Email", value, value.ToString());

				isChanged |= (email != value); email = value;
			}
		}

		/// <summary>
		/// User's name for login to application
		/// </summary>		
		public virtual string Username
		{
			get { return username; }
			set	
			{
				if ( value != null )
					if( value.Length > 50)
						throw new ArgumentOutOfRangeException("Invalid value for Username", value, value.ToString());
				
				isChanged |= (username != value); username = value;
			}
		} 
	  
		/// <summary>
		/// MD5 hash of user's password
		/// </summary>		
		public virtual string Password
		{
			get { return password; }
			set	
			{
				if ( value != null )
					if( value.Length > 32)
						throw new ArgumentOutOfRangeException("Invalid value for Password", value, value.ToString());
				
				isChanged |= (password != value); password = value;
			}
		} 
	  
		/// <summary>
		/// 
		/// </summary>		
		public virtual IList<Album> Albums
		{
			get { return albums; }
			set { isChanged |= (albums != value); albums = value; }
		} 
	  
		/// <summary>
		/// 
		/// </summary>		
		public virtual IList<Comment> Comments
		{
			get { return comments; }
			set { isChanged |= (comments != value); comments = value; }
		} 
	  
		/// <summary>
		/// 
		/// </summary>		
		public virtual IList<Vote> Votes
		{
			get { return votes; }
			set { isChanged |= (votes != value); votes = value; }
		} 
	  
		/// <summary>
		/// Returns whether or not the object has changed it's values.
		/// </summary>
		public virtual bool IsChanged
		{
			get { return isChanged; }
		}
		
		/// <summary>
		/// Returns whether or not the object has changed it's values.
		/// </summary>
		public virtual bool IsDeleted
		{
			get { return isDeleted; }
		}
		
		#endregion 
		
		#region Public Functions

		#endregion
		
		#region Equals And HashCode Overrides
		
		/// <summary>
		/// local implementation of Equals based on unique value members
		/// </summary>
		public override bool Equals( object obj )
		{
			if( this == obj ) return true;
			if( ( obj == null ) || ( obj.GetType() != this.GetType() ) ) return false;
			User castObj = (User)obj; 
			return ( castObj != null ) && ( this.id == castObj.Id );
		}
		
		/// <summary>
		/// local implementation of GetHashCode based on unique value members
		/// </summary>
		public override int GetHashCode()
		{ 
			int hash = 57; 
			hash = 27 * hash * this.id.GetHashCode();
					
			return hash;		
			
		}
		
		#endregion
		
	}
}